
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

/**1
 * FocusNode - Why is requestFocus() not working?
 * https://stackoverflow.com/questions/56221653/focusnode-why-is-requestfocus-not-working
 */
class KeyEventPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('键盘上下键寻焦示例')),
        body: Center(
          child: FocusExample(),
        ),
      ),
    );
  }
}

class FocusExample extends StatefulWidget {
  @override
  _FocusExampleState createState() => _FocusExampleState();
}

class _FocusExampleState extends State<FocusExample> {
  FocusNode focusNode1 = FocusNode();
  FocusNode focusNode2 = FocusNode();
  FocusNode focusNode3 = FocusNode();

  _changeFocus(BuildContext context, FocusNode focusNodeNext) {
    setState(() {
      FocusScope.of(context).requestFocus(focusNodeNext);
    });;
  }
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      FocusScope.of(context).requestFocus(focusNode1); // 自动聚焦
    });
  }

  @override
  void dispose() {
    focusNode1.dispose();
    focusNode2.dispose();
    focusNode3.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return RawKeyboardListener(
      focusNode: FocusNode(),
      onKey: (event) {
        print('RawKeyboardListener '+ event.toString());
        print('focusNode1.hasFocus:'+focusNode1.hasFocus.toString());
        print('focusNode2.hasFocus:'+focusNode2.hasFocus.toString());
        print('focusNode3.hasFocus:'+focusNode3.hasFocus.toString());
        // print(
        if (event is RawKeyDownEvent && event.logicalKey == LogicalKeyboardKey.arrowDown) {
          print('RawKeyboardListener arrowDown '+ event.toString());

          if (focusNode1.hasFocus) {
            // FocusScope.of(context).requestFocus(focusNode2);
            _changeFocus(context, focusNode2);
            print('focusNode2 requestFocus');
          } else if (focusNode2.hasFocus) {
            // FocusScope.of(context).requestFocus(focusNode3);
            _changeFocus(context, focusNode3);
            print('focusNode3 requestFocus');
          } else {
            // FocusScope.of(context).requestFocus(focusNode1);
            print('focusedChild:'+FocusScope.of(context).focusedChild.toString());
            _changeFocus(context, focusNode1);
            print('focusNode1 requestFocus');
          }
        } else if (event is RawKeyDownEvent && event.logicalKey == LogicalKeyboardKey.arrowUp) {
          print('RawKeyboardListener arrowUp '+ event.toString());
          if (focusNode1.hasFocus) {
            FocusScope.of(context).requestFocus(focusNode3);
          } else if (focusNode2.hasFocus) {
            FocusScope.of(context).requestFocus(focusNode1);
          } else if (focusNode3.hasFocus) {
            FocusScope.of(context).requestFocus(focusNode2);
          }
        }
        // return KeyEventResult.handled;
      },
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          GestureDetector(
            onTap: () {
              FocusScope.of(context).requestFocus(focusNode1);
            },
            child: Container(
              width: 200,
              height: 100,
              color: Colors.blue,
              child: Center(
                child: Text('可聚焦容器 1'),
              ),
            ),
          ),
          Focus(
            focusNode: focusNode1,
            child: Container(
              width: 200,
              height: 100,
              color: focusNode1.hasFocus? Colors.green : Colors.blue,
            ),
          ),
          SizedBox(height: 20),
          GestureDetector(
            onTap: () {
              FocusScope.of(context).requestFocus(focusNode2);
            },
            child: Container(
              width: 200,
              height: 100,
              color: Colors.yellow,
              child: Center(
                child: Text('可聚焦容器 2'),
              ),
            ),
          ),
          Focus(
            focusNode: focusNode2,
            child: Container(
              width: 200,
              height: 100,
              color: focusNode2.hasFocus? Colors.green : Colors.yellow,
            ),
          ),
          SizedBox(height: 20),
          GestureDetector(
            onTap: () {
              FocusScope.of(context).requestFocus(focusNode3);
            },
            child: Container(
              width: 200,
              height: 100,
              color: Colors.orange,
              child: Center(
                child: Text('可聚焦容器 3'),
              ),
            ),
          ),
          Focus(
            focusNode: focusNode3,
            child: Container(
              width: 200,
              height: 100,
              color: focusNode3.hasFocus? Colors.green : Colors.orange,
            ),
          ),
        ],
      ),
    );
  }
}

